from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django_filters.rest_framework import DjangoFilterBackend
from drf_yasg.views import get_schema_view
from rest_framework import status, permissions
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from drf_yasg import openapi
from rest_framework.viewsets import ModelViewSet
from rest_framework.serializers import ModelSerializer
from rest_framework_simplejwt.views import TokenObtainPairView

from sers.custom_throttles.throttles import CustomArticleListAnonRateThrottle, CustomArticleListUserRateThrottle
from sers.customfilters.custom_filters import FamilyFilter
from sers.models import Family
from sers.paginations.custom_paginations import CustomPageNumberPagination
from sers.serializer.serializers import CustomTokenObtainPairSerializer

# API自动生成文档视图
schema_view = get_schema_view(
    # API 信息
    openapi.Info(
        title='SQTP API',  # API文档标题
        default_version='V1',  # 版本信息
        description='SQTP 接口文档',  # 描述内容
        terms_of_service='https://test.com',  # 开发团队地址
        contact=openapi.Contact(email='https://test.@163com', url='https://test.com'),  # 联系人信息：邮件、网址
        license=openapi.License(name='Test License'),  # 证书
    ),
    public=True,  # 是否公开
    permission_classes=[permissions.AllowAny]  # 设置用户权限

)


class CustomObtainTokenPairView(TokenObtainPairView):
    """
    自定义token的返回值视图
    """
    permission_classes = (AllowAny,)
    serializer_class = CustomTokenObtainPairSerializer


# 获取django自带的auth_user表
User = get_user_model()


class CustomBackend(ModelBackend):
    # 同时支持邮箱/密码，手机/密码组合登录
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username=username) | Q(email=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None


# 序列化器
class FamilySerializer(ModelSerializer):
    class Meta:
        model = Family
        fields = '__all__'


# user表序列化器
class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        # fields = '__all__'
        exclude = ['id', 'password', 'last_login', 'first_name', 'last_name', 'is_staff', 'is_active', 'date_joined', 'groups']


# djangoauto_user表的视图类，包含增删改查
class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # 需要登录认证才能访问
    permission_classes = (IsAuthenticated,)

    # permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get_permissions(self):
        """
        对于用户注册，不需要登录也可以进行访问
        :return:
        """
        if self.action == 'create':
            return [permissions.AllowAny()]
        return super().get_permissions()

    # 自定义响应格式字段
    # 重写list方法，自定义响应字段
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        data = {
            'status': '1',
            'data': serializer.data
        }
        return Response(data)

    # 单条数据详情，自定义响应字段格式
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = {
            'status': '1',
            'data': serializer.data
        }
        return Response(data, status=status.HTTP_200_OK)

    # 注册django自带auth_user表的用户
    def create(self, request, *args, **kwargs):
        # 获取注册的请求json参数中的密码password
        password = request.data["password"]
        print(password)

        # 自定义返回响应结构：方式1
        # try:
        #     serializer = self.get_serializer(data=request.data)
        #     serializer.is_valid(raise_exception=True)
        #     user_data = serializer.validated_data
        #     user = User.objects.create_user(username=user_data['username'], email=user_data['email'], password=password)
        #     response_data = {
        #         "msg": "注册成功",
        #         'status': "1",
        #         'data': {
        #             "user_id": user.id,
        #             "username": user.username,
        #             "email": user.email
        #         }
        #     }
        #
        #     return Response(response_data, status=status.HTTP_201_CREATED)
        # except Exception as e:
        #     return Response({"status": 0, 'msg': "用户名已存在", 'data': []}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)

        # 自定义返回响应结构：方式2
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            user_data = serializer.validated_data
            user = User.objects.create_user(username=user_data['username'], email=user_data['email'], password=password)
            response_data = {
                "msg": "注册成功",
                'status': "1",
                'data': {
                    "user_id": user.id,
                    "username": user.username,
                    "email": user.email
                }
            }

            return Response(response_data, status=status.HTTP_201_CREATED)
        else:
            return Response({"status": 0, 'msg': "用户名已存在", 'data': []}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)


# 视图类，包含增删改查
class FamilyViewSet(ModelViewSet):
    queryset = Family.objects.all().order_by('id')
    serializer_class = FamilySerializer

    # 使用自定义分页器===================================================================================
    pagination_class = CustomPageNumberPagination

    # 认证，只允许认证通过的人增删改，未认证通过的只允许 查=====================================================
    # permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    permission_classes = (IsAuthenticated,)

    # 添加过滤查询器=====================================================================================
    # 步骤1
    filter_backends = (DjangoFilterBackend,)

    # 方式1.  设置自定义过滤器类作为查询(注意： 这里一定要使用filterset_class，不能使用filter_class)
    filterset_class = FamilyFilter

    # 方式2. 设置哪些字段可以进行过滤查询
    # filterset_fields = ['name', 'age']

    # 使用自定义限流器====================================================================================
    throttle_classes = [CustomArticleListAnonRateThrottle, CustomArticleListUserRateThrottle]

    # 重写list方法，自定义响应字段
    # def list(self, request, *args, **kwargs):
    #     queryset = self.filter_queryset(self.get_queryset())
    #     page = self.paginate_queryset(queryset)
    #
    #     # 如果列表支持分页就加上分页的功能
    #     # 分页数据的响应格式
    #     if page is not None:
    #         serializer = self.get_serializer(page, many=True)
    #         # # 组装响应结构
    #         # data = {
    #         #     'status': '1',
    #         #     'data': serializer.data
    #         # }
    #         return self.get_paginated_response(serializer.data)
    #
    #     # 如果列表不支持分页，上面的分页代码不要写，只写下面的全部数据自定义格式
    #     # 全部数据的响应结构
    #     serializer = self.get_serializer(queryset, many=True)
    #     # 组装响应结构
    #     # data = {
    #     #     'status': '1',
    #     #     'data': serializer.data
    #     # }
    #     return Response(serializer.data)
